package com.ruoyi.business.service.impl;

import com.ruoyi.business.constant.IBusinessConstant;
import com.ruoyi.business.domain.*;
import com.ruoyi.business.domain.field.*;
import com.ruoyi.business.mapper.ExtModelDefInstanceMapper;
import com.ruoyi.business.mapper.ExtModelFieldMapper;
import com.ruoyi.business.mapper.ExtModelFieldRefMapper;
import com.ruoyi.business.service.*;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 模型字段Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-08
 */
@Service
public class ExtModelFieldServiceImpl implements IExtModelFieldService
{
    @Autowired
    private ExtModelFieldMapper extModelFieldMapper;
    @Lazy
    @Autowired
    private IExtModelFieldRefService extModelFieldRefService;
    @Lazy
    @Autowired
    private IExtModelDefService extModelDefService;
    @Autowired
    private IDataSourceService dataSourceService;
    private ExtModelDefInstanceMapper extModelDefInstanceMapper;
    @Autowired
    private ExtModelFieldRefMapper  extModelFieldRefMapper ;
    @Autowired
    private IExtModelFieldMetadataTagService extModelFieldMetadataTagService;
    /**
     * 查询模型字段
     *
     * @param id 模型字段主键
     * @return 模型字段
     */
    @Override
    public ExtModelField selectExtModelFieldById(Long id)
    {
        ExtModelField extModelField = extModelFieldMapper.selectExtModelFieldById(id);
        //私有的，还得装入字段标签
        if(IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())) {
            extModelField.setTagList(getTagListByFieldId(extModelField));
        }
        return extModelField;
    }

    /**
     * 根据字段id获取标签列表
     * @param extModelField
     * @return
     */
    private List<ExtModelFieldMetadataTag> getTagListByFieldId(ExtModelField extModelField) {
        ExtModelFieldMetadataTag extModelFieldMetadataTag = new ExtModelFieldMetadataTag();
        extModelFieldMetadataTag.setExtModelFieldId(extModelField.getId());
        return extModelFieldMetadataTagService.selectExtModelFieldMetadataTagList(extModelFieldMetadataTag);
    }

    /**
     * 查询模型字段列表
     *
     * @param extModelField 模型字段
     * @return 模型字段
     */
    @Override
    public List<ExtModelField> selectExtModelFieldList(ExtModelField extModelField)
    {
        List<ExtModelField> extModelFields = extModelFieldMapper.selectExtModelFieldList(extModelField);
        for (ExtModelField field : extModelFields) {
            if(IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())) {
                field.setTagList(getTagListByFieldId(field));
            }
        }
        return extModelFields;
    }

    /**
     * 新增模型字段
     *
     * @param extModelField 模型字段
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertExtModelField(ExtModelField extModelField)
    {
        checkInsert(extModelField);
        extModelField.setCreateTime(DateUtils.getNowDate());
        extModelField.setCreateBy(SecurityUtils.getUsername());
        int row =  extModelFieldMapper.insertExtModelField(extModelField);
        //如果是私有字段，还得增加引用字段
        if(IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())) {
            ExtModelFieldRef fieldRef = new ExtModelFieldRef();
            fieldRef.setExtModelFieldId(extModelField.getId());
            fieldRef.setDatasourceName(extModelField.getDatasourceName());
            fieldRef.setEnName(extModelField.getEnName());
            fieldRef.setScope(extModelField.getScope());
            fieldRef.setEnterpriseCode(extModelField.getEnterpriseCode());
            fieldRef.setApplicationCode(extModelField.getApplicationCode());
            extModelFieldRefMapper.insertExtModelFieldRef(fieldRef);
            insertTags(extModelField);
            //转换数据类型
            extModelField.setFieldType(getDbType(extModelField.getFieldWidth(),extModelField.getScheme()));
            //切换数据源
            SqlSession sqlSession = null;
            try {
                String key = dataSourceService.getKey(SecurityUtils.getEnterpriseCode(),SecurityUtils.getApplicationCode(),extModelField.getDatasourceName());
                sqlSession = dataSourceService.switchDataSource(key);
                extModelDefInstanceMapper = sqlSession.getMapper(ExtModelDefInstanceMapper.class);
                //原表增加字段
                extModelDefInstanceMapper.addField(extModelField);
            } finally {
                if (sqlSession != null) {
                    sqlSession.close();
                }
            }
        }
        return row;
    }

    /**
     * 插入标签
     * @param extModelField
     */
    private void insertTags(ExtModelField extModelField) {
        ExtModelFieldMetadataTag extModelFieldMetadataTag = null;
        //删除这个字段的标签(对于更新情况）
        extModelFieldMetadataTagService.deleteExtModelFieldMetadataTagByFieldId(extModelField.getId());
        for(ExtModelFieldMetadataTag tag:extModelField.getTagList()){
            extModelFieldMetadataTag = new ExtModelFieldMetadataTag();
            extModelFieldMetadataTag.setExtModelFieldId(extModelField.getId());
            extModelFieldMetadataTag.setTagName(tag.getTagName());
            extModelFieldMetadataTag.setEnterpriseCode(extModelField.getEnterpriseCode());
            extModelFieldMetadataTag.setApplicationCode(extModelField.getApplicationCode());
            extModelFieldMetadataTag.setCreateBy(SecurityUtils.getUsername());
            extModelFieldMetadataTag.setCreateTime(DateUtils.getNowDate());
            extModelFieldMetadataTag.setUpdateBy(SecurityUtils.getUsername());
            extModelFieldMetadataTag.setUpdateTime(DateUtils.getNowDate());

            extModelFieldMetadataTagService.insertExtModelFieldMetadataTag(extModelFieldMetadataTag);
        }
    }

    /**
     * 检查插入数据
     * @param extModelField
     */
    private void checkInsert(ExtModelField extModelField) {
        //如果信息范围是私有的，则表英文名必填
        if(IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())){
            if(StringUtils.isEmpty(extModelField.getEnName()))
                throw new ServiceException("私有字段必传表名!");
        }
        //检查字段英文，字段中文名是否重复
        Map<String,Object> searchMap = new HashMap<>();
        //非私有字段判断：同一个信息范围不能重复
        if(!IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())) {
            searchMap.put("scope", extModelField.getScope());
            searchMap.put("fieldEnName", extModelField.getFieldEnName());
            if (extModelFieldMapper.selectCount(searchMap) > 0)
                throw new ServiceException("信息范围："+translateScope(extModelField.getScope())+"已经存在字段名:"+ extModelField.getFieldEnName());
            searchMap.clear();
            searchMap.put("scope", extModelField.getScope());
            searchMap.put("fieldCnName", extModelField.getFieldCnName());
            if (extModelFieldMapper.selectCount(searchMap) > 0)
                throw new ServiceException("信息范围："+translateScope(extModelField.getScope())+"已经存在字段名:"+ extModelField.getFieldCnName());
        }else{
            //私有范围，同一个数据源，同一个英文表名不能重复(关联字段定义表查询)
            searchMap.put("datasourceName", extModelField.getDatasourceName());
            searchMap.put("enName", extModelField.getEnName());
            searchMap.put("fieldEnName", extModelField.getFieldEnName());
            if(extModelFieldRefMapper.selectCountAssociation(searchMap)>0)
                throw new ServiceException("字段名:"+ extModelField.getFieldEnName()+"已经存在!");
            searchMap.put("fieldCnName", extModelField.getFieldCnName());
            searchMap.remove("fieldEnName");
            if(extModelFieldRefMapper.selectCountAssociation(searchMap)>0)
                throw new ServiceException("字段名:"+ extModelField.getFieldCnName()+"已经存在!");
            //标签不能为空，至少有一条
            if(extModelField.getTagList()==null || extModelField.getTagList().size()==0)
                throw new ServiceException("标签不能为空!");
        }

    }

    /**
     * 翻译信息范围
     * @param scope
     * @return
     */
    private String translateScope(String scope) {
        if(IBusinessConstant.SCOPE_ENTITY_DEFAULT.equals(scope)){
            return "业务默认字段";
        }else if(IBusinessConstant.SCOPE_WORKFLOW_DEFAULT.equals(scope)){
            return "流程默认字段";
        }else if(IBusinessConstant.SCOPE_GLOBAL.equals(scope)){
            return "全局";
        }else if(IBusinessConstant.SCOPE_PRIVATE.equals(scope)){
            return "私有字段";
        }else
            return "";
    }

    /**
     * 修改模型字段
     *
     * @param extModelField 模型字段
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateExtModelField(ExtModelField extModelField)
    {
        checkUpdate(extModelField);
        extModelField.setUpdateTime(DateUtils.getNowDate());
        ExtModelField orgExtModelField = extModelFieldMapper.selectExtModelFieldById(extModelField.getId());

        int row =  extModelFieldMapper.updateExtModelField(extModelField);
        //重新插入标签
        if(IBusinessConstant.SCOPE_PRIVATE.equals(orgExtModelField.getScope())) {
            insertTags(extModelField);
        }
        //如果字段已经被引用，只能修改长度
        int refCount =0;
        {
            ExtModelFieldRef extModelFieldRef;
            extModelFieldRef = new ExtModelFieldRef();
            extModelFieldRef.setExtModelFieldId(extModelField.getId());
            refCount = extModelFieldRefMapper.selectCount(extModelFieldRef);
            if (refCount > 0) {
                if (!orgExtModelField.getFieldEnName().equals(extModelField.getFieldEnName()))
                    throw new ServiceException("字段已经被引用，不能改字段");
                if (!orgExtModelField.getFieldCnName().equals(extModelField.getFieldCnName()))
                    throw new ServiceException("字段已经被引用，不能改标签");
                if (!orgExtModelField.getFfieldRemark().equals(extModelField.getFfieldRemark()))
                    throw new ServiceException("字段已经被引用，不能改说明");
                if (!orgExtModelField.getFieldType().equals(extModelField.getFieldType()))
                    throw new ServiceException("字段已经被引用，不能改类型!");
            }
        }
        //查询引用字段列表
        ExtModelFieldRef extModelFieldRef;
        extModelFieldRef = new ExtModelFieldRef();
        extModelFieldRef.setExtModelFieldId(extModelField.getId());
        List<ExtModelFieldRef> extModelFieldRefs = extModelFieldRefMapper.selectExtModelFieldRefList(extModelFieldRef);

        //如果是宽度变化，则切换数据源，修改表字段长度
        Long fieldWidth = orgExtModelField.getFieldWidth()==null?0L:orgExtModelField.getFieldWidth();
        if(!fieldWidth.equals(extModelField.getFieldWidth()) && refCount==0){
            //循环修改引用表的字段长度
            for(ExtModelFieldRef extModelFieldRef1:extModelFieldRefs){
                //切换数据源
                SqlSession sqlSession = null;
                try {
                    String key = dataSourceService.getKey(SecurityUtils.getEnterpriseCode(),SecurityUtils.getApplicationCode(),extModelFieldRef.getDatasourceName());
                    sqlSession = dataSourceService.switchDataSource(key);
                    //修改字段
                    TableField tableField = new TableField();
                    String dbType = getDbType(extModelField.getFieldWidth(), extModelField.getScheme());
                    tableField.setFieldType(dbType);
                    tableField.setFieldName(extModelField.getFieldEnName());
                    tableField.setPrimaryKey("");
                    tableField.setComment(extModelField.getFieldCnName());
                    tableField.setNullLabel("NULL");
                    tableField.setAutoIncrement("");
                    extModelDefInstanceMapper = sqlSession.getMapper(ExtModelDefInstanceMapper.class);
                    extModelDefInstanceMapper.modifyField(extModelFieldRef1.getEnName(),tableField);
                }finally {
                    if(sqlSession!=null){
                        sqlSession.close();
                    }
                }
            }
        }else{
            //循环修改引用表的字段长度
            for(ExtModelFieldRef extModelFieldRef1:extModelFieldRefs){
                //切换数据源
                SqlSession sqlSession = null;
                try {
                    String key = dataSourceService.getKey(SecurityUtils.getEnterpriseCode(),SecurityUtils.getApplicationCode(),extModelFieldRef.getDatasourceName());
                    sqlSession = dataSourceService.switchDataSource(key);
                    //修改字段
                    TableField tableField = new TableField();
                    String dbType = getDbType(extModelField.getFieldWidth(), extModelField.getScheme());
                    tableField.setFieldType(dbType);
                    tableField.setFieldName(extModelField.getFieldEnName());
                    tableField.setPrimaryKey("");
                    tableField.setComment(extModelField.getFieldCnName());
                    tableField.setNullLabel("NULL");
                    tableField.setAutoIncrement("");
                    extModelDefInstanceMapper = sqlSession.getMapper(ExtModelDefInstanceMapper.class);
                    extModelDefInstanceMapper.modifyAllField(extModelFieldRef1.getEnName(),orgExtModelField.getFieldEnName(),tableField);
                }finally {
                    if(sqlSession!=null){
                        sqlSession.close();
                    }
                }
            }
        }

        return row;
    }

    /**
     * 检查更新数据
     * @param extModelField
     */
    private void checkUpdate(ExtModelField extModelField) {
        if(extModelField ==null)
            throw new ServiceException("更新对象为空!");
        if(extModelField.getId()==null|| extModelField.getId()==0L)
            throw new ServiceException("更新id为空！");
        ExtModelField orgExtModelField = extModelFieldMapper.selectExtModelFieldById(extModelField.getId());
        //检查字段英文，字段中文名是否重复
        Map<String,Object> searchMap = new HashMap<>();
        //非私有字段判断：同一个信息范围不能重复
        if(!IBusinessConstant.SCOPE_PRIVATE.equals(orgExtModelField.getScope())) {
            searchMap.put("notId", extModelField.getId());
            searchMap.put("scope", extModelField.getScope());
            searchMap.put("fieldEnName", extModelField.getFieldEnName());
            if (extModelFieldMapper.selectCount(searchMap) > 0)
                throw new ServiceException("信息范围："+translateScope(extModelField.getScope())+"已经存在字段名:"+ extModelField.getFieldEnName());
            searchMap.clear();
            searchMap.put("notId", extModelField.getId());
            searchMap.put("scope", extModelField.getScope());
            searchMap.put("fieldCnName", extModelField.getFieldCnName());
            if (extModelFieldMapper.selectCount(searchMap) > 0)
                throw new ServiceException("信息范围："+translateScope(extModelField.getScope())+"已经存在字段名:"+ extModelField.getFieldCnName());
        }else{
            //私有范围，同一个数据源，同一个英文表名不能重复(关联字段定义表查询)
            searchMap.put("datasourceName", extModelField.getDatasourceName());
            searchMap.put("enName", extModelField.getEnName());
            searchMap.put("fieldEnName", extModelField.getFieldEnName());
            searchMap.put("notId", extModelField.getId());
            if(extModelFieldRefMapper.selectCountAssociation(searchMap)>0)
                throw new ServiceException("字段名:"+ extModelField.getFieldEnName()+"已经存在!");
            searchMap.put("fieldCnName", extModelField.getFieldCnName());
            searchMap.remove("fieldEnName");
            if(extModelFieldRefMapper.selectCountAssociation(searchMap)>0)
                throw new ServiceException("字段名:"+ extModelField.getFieldCnName()+"已经存在!");
            //字段标签不能为空
            if(extModelField.getTagList()==null||extModelField.getTagList().size()==0)
                throw new ServiceException("字段标签不能为空!");

        }

    }

    /**
     * 批量删除模型字段
     *
     * @param ids 需要删除的模型字段主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteExtModelFieldByIds(Long[] ids)
    {
        int sum =0;
        for(Long id:ids){
            sum +=deleteExtModelFieldById(id);
        }
        return sum;
    }
    public String getDbType(long width, FieldScheme fieldScheme) {
        String dbType = "VARCHAR(" + width + ")";
        FieldType type = fieldScheme.getType();
        if (type == FieldType.user) {
            UserFieldScheme scheme = (UserFieldScheme) fieldScheme;
            if (!Boolean.TRUE.equals(scheme.getMultiple())) {
                dbType = "BIGINT UNSIGNED";
            }
        }
        else if (type == FieldType.option) {
            OptionFieldScheme scheme = (OptionFieldScheme) fieldScheme;
            if (!Boolean.TRUE.equals(scheme.getMultiple())) {
                dbType = "BIGINT UNSIGNED";
            }
        }
        else if (type == FieldType.dept) {
            DeptFieldScheme scheme = (DeptFieldScheme) fieldScheme;
            if (!Boolean.TRUE.equals(scheme.getMultiple())) {
                dbType = "BIGINT UNSIGNED";
            }
        }
        else if (type == FieldType.number) {
            NumberInputFieldScheme scheme = (NumberInputFieldScheme) fieldScheme;
            if (Integer.valueOf(0).equals(scheme.getPrecision())) {
                dbType = "BIGINT UNSIGNED";
            } else {
                dbType = "DECIMAL(65," + scheme.getPrecision() + ")";
            }
        }
        else if (type == FieldType.date) {
            DateFieldScheme scheme = (DateFieldScheme) fieldScheme;
            if(DateFieldScheme.DateType.datetime.equals(scheme.getDateType())) {
                dbType = scheme.getDateType().toString();
            }else{
                dbType = DateFieldScheme.DateType.date.toString();
            }
        }
        //dateType
        return dbType;
    }

    /**
     * 查询某模型实体字段列表（含私有，缺省，全局)
     *
     * @param extModelField 必须有数据源+表英文名
     * @return 模型实体字段列表
     */
    @Override
    public List<ExtModelField> selectModelField(ExtModelField extModelField) {
        //校验数据源，表英文名必填
        if(extModelField== null)
            throw new ServiceException("查询对象为空！");
        if(StringUtils.isEmpty(extModelField.getDatasourceName())||
           StringUtils.isEmpty(extModelField.getEnName()))
            throw new ServiceException("数据源名称和表英文必传！");
        //查询表类型
        ExtModelDef extModelDef;
        extModelDef = new ExtModelDef();
        extModelDef.setEnName(extModelField.getEnName());
        extModelDef.setDatasourceName(extModelField.getDatasourceName());
        List<ExtModelDef> extModelDefList = extModelDefService.selectExtModelDefList(extModelDef);
        if(CollectionUtils.isEmpty(extModelDefList))
            throw new ServiceException("数据源："+extModelField.getDatasourceName()+",表英文名:"+extModelField.getEnName()+"在实体模型不存在!");
        ExtModelDef extModelDef1 = extModelDefList.get(0);
        if(IBusinessConstant.TABLE_TYPE_01.equals(extModelDef1.getTableType())){
            extModelField.setScope(IBusinessConstant.SCOPE_ENTITY_DEFAULT);
        }else{
            extModelField.setScope(IBusinessConstant.SCOPE_WORKFLOW_DEFAULT);
        }
        List<ExtModelField> extModelFields = extModelFieldMapper.selectModelField(extModelField);
        for(ExtModelField field:extModelFields){
            if(field.getScope().equals(IBusinessConstant.SCOPE_PRIVATE)){
                field.setTagList(getTagListByFieldId(field));
            }
        }
        return extModelFields;
    }

    /**
     * 根据引用字段id，数据源名称，表英文名 删除模型字段
     *
     * @param extModelField
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByExtModelField(ExtModelField extModelField) {
        //校验数据源，表英文名必填
        if(extModelField== null)
            throw new ServiceException("查询对象为空！");
        if(StringUtils.isEmpty(extModelField.getDatasourceName())||
                StringUtils.isEmpty(extModelField.getEnName()))
            throw new ServiceException("数据源名称和表英文必传！");
        if(extModelField.getId()==null||extModelField.getId()==0L)
            throw new ServiceException("字段id（即引用id）必传!");
        ExtModelFieldRef extModelFieldRef;
        extModelFieldRef = new ExtModelFieldRef();
        extModelFieldRef.setExtModelFieldId(extModelField.getId());
        extModelFieldRef.setDatasourceName(extModelField.getDatasourceName());
        extModelFieldRef.setEnName(extModelField.getEnName());
        List<ExtModelFieldRef> extModelFieldRefs = extModelFieldRefMapper.selectExtModelFieldRefList(extModelFieldRef);
        int row =  extModelFieldMapper.removeByExtModelField(extModelField);
        //如果是私有范围字段，还是删除字段标签
        if(extModelField.getScope() == IBusinessConstant.SCOPE_PRIVATE){
            extModelFieldMetadataTagService.deleteExtModelFieldMetadataTagByFieldId(extModelField.getId());
        }
        if(!CollectionUtils.isEmpty(extModelFieldRefs)) {
            ExtModelField dbExtModelField = selectExtModelFieldById(extModelField.getId());
            //业务表执行删除字段
            SqlSession sqlSession = null;
            for (ExtModelFieldRef extModelFieldRef1 : extModelFieldRefs) {
                //切换数据源
                try {
                    String key = dataSourceService.getKey(SecurityUtils.getEnterpriseCode(),SecurityUtils.getApplicationCode(),extModelFieldRef1.getDatasourceName());
                    sqlSession = dataSourceService.switchDataSource(key);
                    extModelDefInstanceMapper = sqlSession.getMapper(ExtModelDefInstanceMapper.class);
                    extModelDefInstanceMapper.dropField(extModelFieldRef1.getEnName(), dbExtModelField.getFieldEnName());
                } finally {
                    if (sqlSession != null) {
                        sqlSession.close();
                    }
                }
            }
        }
        return row;
    }

    /**
     * 根据数据源名称+表英文名查询所有字段
     *
     * @param extModelDef
     * @return
     */
    @Override
    public List<ExtModelField> selectAllFieldsByDsAndEnName(ExtModelDef extModelDef) {
        List<ExtModelField> extModelFields = extModelFieldMapper.selectAllFieldsByDsAndEnName(extModelDef);
        for(ExtModelField extModelField:extModelFields){
            //如果是私有范围字段，还是查询标签
            if(IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())){
                extModelField.setTagList(getTagListByFieldId(extModelField));
            }
        }
        return extModelFields;
    }

    /**
     * 根据数据源名称+表英文名+信息范围查询字段定义
     *
     * @param extModelFieldRef
     * @return
     */
    @Override
    public List<ExtModelField> selectExtModelFieldRefByModel(ExtModelFieldRef extModelFieldRef) {
        List<ExtModelField> extModelFields = extModelFieldMapper.selectExtModelFieldRefByModel(extModelFieldRef);
        for(ExtModelField extModelField:extModelFields){
            //如果是私有范围字段，还是查询标签
            if(IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())){
                extModelField.setTagList(getTagListByFieldId(extModelField));
            }
        }

        return extModelFields;
    }

    /**
     * 删除模型字段信息
     *
     * @param id 模型字段主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteExtModelFieldById(Long id)
    {
        //删除前检查
        ExtModelField extModelField = extModelFieldMapper.selectExtModelFieldById(id);
        if(extModelField==null)
            throw new ServiceException("记录不存在!");
        //禁止删除默认字段
//        if(IBusinessConstant.SCOPE_ENTITY_DEFAULT.equals(extModelField.getScope())||
//           IBusinessConstant.SCOPE_WORKFLOW_DEFAULT.equals(extModelField.getScope()) )
//            throw new ServiceException("缺省字段不能删除！");
        //全局字段，先解绑与之有关实体表
        if(IBusinessConstant.SCOPE_GLOBAL.equals(extModelField.getScope())){
            ExtModelFieldRef extModelFieldRef;
            extModelFieldRef = new ExtModelFieldRef();
            extModelFieldRef.setExtModelFieldId(id);
            if(extModelFieldRefMapper.selectCount(extModelFieldRef)>0)
                throw new ServiceException("删除全局字段前请先解绑与其关联的流程");
        }else if(IBusinessConstant.SCOPE_WORKFLOW_DEFAULT.equals(extModelField.getScope())||
                IBusinessConstant.SCOPE_ENTITY_DEFAULT.equals(extModelField.getScope())){
            ExtModelFieldRef extModelFieldRef;
            extModelFieldRef = new ExtModelFieldRef();
            extModelFieldRef.setExtModelFieldId(id);
            if(extModelFieldRefMapper.selectCount(extModelFieldRef)>0)
                throw new ServiceException("缺省字段已经被引用无法删除!");
        }
        //TODO:检查页面引用字段
        ExtModelFieldRef extModelFieldRef;
        extModelFieldRef = new ExtModelFieldRef();
        extModelFieldRef.setExtModelFieldId(id);
        List<ExtModelFieldRef> extModelFieldRefs = extModelFieldRefMapper.selectExtModelFieldRefList(extModelFieldRef);
        int row =  extModelFieldMapper.deleteExtModelFieldById(id);
        if(!CollectionUtils.isEmpty(extModelFieldRefs)) {
            List<Long> ids = extModelFieldRefs.stream()
                    .map(ExtModelFieldRef::getId)
                    .collect(Collectors.toList());
            extModelFieldRefMapper.deleteExtModelFieldRefByIds((Long[]) ids.toArray(new Long[ids.size()]));
            //业务表执行删除字段
            SqlSession sqlSession = null;
            for (ExtModelFieldRef extModelFieldRef1 : extModelFieldRefs) {
                //切换数据源
                try {
                    String key = dataSourceService.getKey(SecurityUtils.getEnterpriseCode(),SecurityUtils.getApplicationCode(),extModelFieldRef1.getDatasourceName());
                    sqlSession = dataSourceService.switchDataSource(key);
                    extModelDefInstanceMapper = sqlSession.getMapper(ExtModelDefInstanceMapper.class);
                    extModelDefInstanceMapper.dropField(extModelFieldRef1.getEnName(), extModelField.getFieldEnName());
                } finally {
                    if (sqlSession != null) {
                        sqlSession.close();
                    }
                }
            }
        }
        //如果是私有字段，还得删除字段标签
        if(extModelField.getScope().equals(IBusinessConstant.SCOPE_PRIVATE)){
            extModelFieldMetadataTagService.deleteExtModelFieldMetadataTagByFieldId(extModelField.getId());
        }
        return row;
    }

    /**
     * 根据模型表英文名删除
     *
     * @param extModelDef 表英文名
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteExtModelFieldByTableName(ExtModelDef extModelDef) {
        //如果是私有范围字段，还是得删除字段标签
        List<ExtModelField> fields = extModelFieldMapper.selectAllFieldsByDsAndEnName(extModelDef);
        for(ExtModelField field:fields){
            if(field.getScope().equals(IBusinessConstant.SCOPE_PRIVATE)) {
                extModelFieldMetadataTagService.deleteExtModelFieldMetadataTagByFieldId(field.getId());
            }
        }
        //先删除模型字段（范围为私有的)
        extModelFieldMapper.deleteExtModelFieldByTableName(extModelDef);
        //后删除模型字段引用
        return extModelFieldRefService.deleteByTableName(extModelDef);
    }

    /**
     * 通过数据源名称和表英文名非翻页查询模型字段列表(模型字段和字段引用表关联)
     *
     * @param extModelFieldRef
     */
    @Override
    public List<ExtModelField> selectExtModelFieldListRef(ExtModelFieldRef extModelFieldRef) {
        //查询模型表定义
        ExtModelDef extModelDef = new ExtModelDef();
        extModelDef.setEnName(extModelFieldRef.getEnName());
        extModelDef.setDatasourceName(extModelFieldRef.getDatasourceName());
        List<ExtModelDef> modelDefList = extModelDefService.selectExtModelDefList(extModelDef);
        if(CollectionUtils.isEmpty(modelDefList))
            throw new ServiceException("根据表英文名："+extModelFieldRef.getEnName()+
                    ",数据源名称:"+extModelDef.getDatasourceName()+"找不到模型表定义！");
        String scope;
        ExtModelDef extModelDef1 = modelDefList.get(0);
        //纯业务表
        if(extModelDef1.getTableType().equals(IBusinessConstant.TABLE_TYPE_01)){
            scope=IBusinessConstant.SCOPE_ENTITY_DEFAULT;
        }else{
            scope=IBusinessConstant.SCOPE_WORKFLOW_DEFAULT;
        }
        List<ExtModelField> extModelFields = extModelFieldMapper.selectExtModelFieldListRef(extModelFieldRef, scope);
        for(ExtModelField extModelField:extModelFields){
            //如果是私有范围字段，还是查询标签
            if(IBusinessConstant.SCOPE_PRIVATE.equals(extModelField.getScope())){
                extModelField.setTagList(getTagListByFieldId(extModelField));
            }
        }
        return extModelFields;
    }
}
